package com.starblink.login.editpersonalinfo.ui

import com.blankj.utilcode.util.EncodeUtils
import com.blankj.utilcode.util.EncryptUtils
import com.starblink.android.basic.widget.LoadingDialogManager
import com.starblink.basic.log.SKLogger
import com.starblink.rocketreserver.StsUploadUserHeadImgQuery
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.MultipartBody
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.logging.HttpLoggingInterceptor
import org.joda.time.DateTime
import org.joda.time.DateTimeZone
import org.joda.time.format.ISODateTimeFormat
import java.io.File
import java.io.IOException

/**
 * 用户头像上传阿里云助手
 */
object HeadImageOssUploader {
    private const val TAG = "OssUploader"

    private val client = OkHttpClient.Builder()
        .addInterceptor(HttpLoggingInterceptor()
            .apply {
                setLevel(HttpLoggingInterceptor.Level.HEADERS)
            }).build()

    /**
     * 将图片上传至阿里云，上传成功返回图片URL，上传失败返回null
     */
    suspend fun upload(
        file: File,
        data: StsUploadUserHeadImgQuery.StsUploadUserHeadImg
    ): String? {
        if (data.url.isNullOrEmpty()) return null
        return withContext(Dispatchers.IO) {
            SKLogger.e("dss", "2上传图片isShowing=${LoadingDialogManager.get().isShowing}")
            val url = data.url!!
            val key = "${data.filePath}${File.separator}${DateTime.now().millis}_${file.name}"
            val encodedPolicy = assembleUserHeadPolicy()
            val signature = calculateOssSignature(
                encodedPolicy = encodedPolicy,
                accessKeySecret = data.stsAccessKeySecret
            )
//            SKLogger.e("dss", "data.filePath=${data.filePath}")
//            SKLogger.e("dss", "file.name=${file.name}")
//            SKLogger.e("dss", "encodedPolicy=${encodedPolicy}")
//            SKLogger.e("dss", "signature=${signature}")
            // 注意：不要修改参数次序！！！
            val builder = MultipartBody.Builder()
                .addFormDataPart("key", key)
                .addFormDataPart("success_action_status", "200")
                .addFormDataPart("OSSAccessKeyId", data.stsAccessKeyId)

            if (!data.stsSecurityToken.isNullOrEmpty()) {
                builder.addFormDataPart("x-oss-security-token", data.stsSecurityToken!!)
            }

            builder.addFormDataPart("policy", encodedPolicy)
                .addFormDataPart("Signature", signature)
                .addFormDataPart("Content-Type", "image/jpeg")
                .addFormDataPart("x-oss-content-type", "image/jpeg")
                .addFormDataPart("file", file.name, file.asRequestBody())
                .setType(MultipartBody.FORM)

            val call = client.newCall(
                Request.Builder()
                    .url(url)
                    .post(
                        builder.build()
                    ).build()
            )
            try {
                if (call.execute().isSuccessful) {
                    // 图片上传成功，返回最终的图片URL
                    SKLogger.e("dss", "3上传图片isShowing=${LoadingDialogManager.get().isShowing}")
                    SKLogger.e("dss", "图片上传成功")
                    "$url/$key"
                } else {
                    SKLogger.e("dss", "4上传图片isShowing=${LoadingDialogManager.get().isShowing}")
                    null
                }
            } catch (e: IOException) {
                e.printStackTrace()
                SKLogger.e("dss", e.toString())
                null
            } catch (e: Exception) {
                e.printStackTrace()
                SKLogger.e("dss", e.toString())
                null
            }
        }
    }

    /**
     * 生成用户头像Policy
     * @note （1）100年过期（2）图片大小不能超过5G
     */
    private fun assembleUserHeadPolicy(): String {
        // 100年过期
        var time = DateTime.now(DateTimeZone.UTC).plusYears(100)
        val isoTime = ISODateTimeFormat.dateTime().print(time)
        val res =
            "{\"expiration\": \"${isoTime}\",\"conditions\": [[\"content-length-range\", 0, ${(5.toDouble() * 1024 * 1024 * 1024).toInt()}]]}"
        SKLogger.e("dss", res)
        return EncodeUtils.base64Encode2String(res.toByteArray(Charsets.UTF_8))
    }

    /**
     * 生成阿里云oss的加密参数Signature
     */
    private fun calculateOssSignature(encodedPolicy: String, accessKeySecret: String): String {
        return EncodeUtils.base64Encode2String(
            EncryptUtils.encryptHmacSHA1(
                encodedPolicy.toByteArray(Charsets.UTF_8),
                accessKeySecret.toByteArray(Charsets.UTF_8)
            )
        )
    }
}